package com.mrd.gtimp.init;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;

import com.mrd.gtimp.business.repository.CargoDeclaRecordDao;
import com.mrd.gtimp.service.client.CtmsServiceClient;
import com.mrd.gtimpframe.entity.CargoDeclaRecord;
import com.mrd.gtimpframe.entity.ComDeclaWay;
import com.mrd.gtimpframe.entity.Declaration;
import com.mrd.gtimpframe.repository.CargoDeclaRecordMapper;
import com.mrd.gtimpframe.repository.ComDeclaWayMapper;
import com.mrd.gtimpframe.repository.DeclarationMapper;
import com.mrd.util.PropertiesUtil;
import com.mrd.util.StringUtils;

import bean.query.InvNoReceipt;
import bean.query.InvResult;
import bean.query.QueryResult;
import helper.QueryHelper;

/**
 * Created by dengdc on 2017/5/26.
 */
public class QueryCargoDeclaRunnable implements Runnable  {
    private DeclarationMapper declarationMapper;
    private CargoDeclaRecordDao cargoDeclaRecordDao;
    private CargoDeclaRecordMapper cargoDeclaRecordMapper;
    private Logger logger = LoggerFactory.getLogger(QueryCargoDeclaRunnable.class);
    private ComDeclaWayMapper comDeclaWayMapper;

    public QueryCargoDeclaRunnable(ApplicationContext applicationContext){
        this.cargoDeclaRecordMapper = applicationContext.getBean(CargoDeclaRecordMapper.class);
        this.declarationMapper = applicationContext.getBean(DeclarationMapper.class);
        this.comDeclaWayMapper = applicationContext.getBean(ComDeclaWayMapper.class);
    }

    @Override
    public void run() {
        List<String> noQueryStatus = new ArrayList<>();
        noQueryStatus.add("22");//结关
        noQueryStatus.add("10");//不被受理
        noQueryStatus.add("5");//申报失败
        while (true){
            try {
                long beginTime = System.currentTimeMillis();
                System.err.println("Starting Query All Guangzhou Port Declaration's Receipt");
                List<CargoDeclaRecord> records = cargoDeclaRecordMapper.selectByUploadWayAndStatusNotIn(ComDeclaWay.WayCodeEnum.GZ_PORT_HTTPS.toString(), noQueryStatus);
                Map<String, List<CargoDeclaRecord>> classifyMap = groupRecords(records);
                for (List<CargoDeclaRecord> recordList : classifyMap.values()) {
                    //最多50个一次查询
                    for (int i = 0; i < recordList.size(); i+=50) {
                        int end = i + 50;
                        if(end > recordList.size()){
                            end = recordList.size();
                        }
                        System.err.println("Query Receipts[" + i  + ", " + end +"]");
                        List<CargoDeclaRecord> subList = recordList.subList(i, end);
                        doQuery(subList);
                    }
                }
                Thread.sleep(10 * 60 * 1000);
                System.err.println("Got All Query Guangzhou Port Declaration's Receipt. spend times(millis) " + (System.currentTimeMillis() - beginTime));
            }catch (Exception e){
                e.printStackTrace();
                try {
                    Thread.sleep(10 * 60 * 1000);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }

    private void doQuery(List<CargoDeclaRecord> records){
        List<String> invNos = new ArrayList<>();
        for (CargoDeclaRecord record : records) {
            invNos.add(record.getInvNo());
        }
        CargoDeclaRecord record0 = records.get(0);
        List<String> declarationIds = records.stream().map(CargoDeclaRecord::getDid).collect(Collectors.toList());
        List<Declaration> declarations = declarationMapper.selectSimpleDeclarationByIdIn(declarationIds);

        QueryHelper helper = new QueryHelper();
        String url = PropertiesUtil.getConfigProperties("query.url");
        helper.setCompanyId(record0.getCompanyId());
        helper.setInvNos(invNos);
        helper.setUrl(url);
        try {
            long beginTime = System.currentTimeMillis();
            System.err.println("Starting Query Guangzhou Port Declaration's Receipt");
            QueryResult result = helper.doQuery();
            System.err.println("got Query Guangzhou Port Declaration's Receipt. spend times(millis) " + (System.currentTimeMillis() - beginTime));
            List<InvNoReceipt> receipts = result.getReceipts();
            for (InvNoReceipt receipt : receipts) {
                String receiptInvNo = receipt.getInvNo();
                for (CargoDeclaRecord record : records) {
                    if(receiptInvNo.equals(record.getInvNo())){
                        InvResult invResult = receipt.getInvResult();
                        record.setStatus(invResult.getCustomsStatus());
                        record.setUpdateTime(new Date());
                        record.setEntryNo(invResult.getCustomsEntyNo()); //报关号
                    }
                }
            }
            /*
             * 解析查询结果
             */
            List<Declaration> updateDeclarations = new ArrayList<>();
            for (Declaration declaration : declarations) {
                for (CargoDeclaRecord record : records) {
                    String entyNo = record.getEntryNo();

                    if(record.getDid().equals(declaration.getId()) && StringUtils.isNotEmpty(entyNo) && !entyNo.equals(declaration.getSno())){
                        declaration.setSno(entyNo);
                        updateDeclarations.add(declaration);

                        //更新新港系统报关单号
                        try {
                            new CtmsServiceClient().updateSno(record.getDid(), entyNo);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            if(CollectionUtils.isNotEmpty(updateDeclarations)){
                declarationMapper.batchUpdateSelective(declarations);
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("自动更新海关状态时失败：" + e.getMessage());
        }
        cargoDeclaRecordMapper.batchUpdateByPrimaryKey(records);
    }

    private Map<String, List<CargoDeclaRecord>> groupRecords(List<CargoDeclaRecord> records){
        Map<String, List<CargoDeclaRecord>> result = new HashMap<>();
        for (CargoDeclaRecord record : records) {
            String comId = record.getCompanyId();
            List<CargoDeclaRecord> comRecords = result.computeIfAbsent(comId, k -> new ArrayList<>());
            comRecords.add(record);
        }
        return result;
    }
}
